home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / gc.h < prev    next >
C/C++ Source or Header  |  1998-09-15  |  12KB  |  334 lines

  1. /*
  2.  * @(#)gc.h    1.11 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. #ifndef _GC_H_
  16. #define _GC_H_
  17.  
  18. #include "gc_md.h"
  19.  
  20.  
  21. /*
  22.  * Lock against heap modification.
  23.  */
  24. extern sys_mon_t *_heap_lock;
  25. #define HEAP_LOCK_INIT()    monitorRegister(_heap_lock, "Heap lock")
  26. #define HEAP_LOCK()        sysMonitorEnter(_heap_lock)
  27. #define HEAP_UNLOCK()        sysMonitorExit(_heap_lock)
  28. #define HEAP_LOCKED()        sysMonitorEntered( _heap_lock)
  29.  
  30. /*
  31.  * Define this if you want the mark phase to detect pointers into the
  32.  * interior of objects.
  33.  */
  34. /* #define CHECK_INTERIOR_POINTERS */
  35.  
  36. #define OBJECTGRAIN     8
  37. #define HANDLEGRAIN     8
  38. #define BITSPERCHAR     8
  39.  
  40. /*
  41.  * Types of overflows: we might respond to an overflow of a particular
  42.  * error differently, e.g. expanding only the overflowing area.
  43.  */
  44. #define OVERFLOW_NONE     0
  45. #define OVERFLOW_OBJECTS 1
  46. #define OVERFLOW_HANDLES 2
  47.  
  48. /*
  49.  * Possible actions to take on overflows.  manageAllocFailure()
  50.  * decides between these.
  51.  */
  52. #define OVERFLOW_ACT_FAIL    0
  53. #define OVERFLOW_ACT_GC        1
  54. #define OVERFLOW_ACT_FINALIZE    2
  55. #define OVERFLOW_ACT_REFS    3
  56. #define OVERFLOW_ACT_EXPAND    4
  57. #define OVERFLOW_ACT_DESPERATE    5
  58.  
  59. /*
  60.  * Memory block header (bottom three bits are flags):
  61.  *
  62.  * -------------------------------------------------------------
  63.  * | <--- length --->| pinned | <- obj swapped -> | <- free -> |
  64.  * -------------------------------------------------------------
  65.  * 31             3          2              1           0
  66.  */
  67. typedef long hdr;
  68.  
  69. #define obj_geth(p) (*((hdr *)(p)))
  70. #define obj_seth(p, h) (*((hdr *)(p)) = (h))
  71. #define h_len(h) ((h) & ~(OBJECTGRAIN-1))
  72. #define h_free(h) ((h) & 1)
  73. #define h_bumplen(h, l) ((h) += (l))
  74.  
  75. #define obj_len(p) (obj_geth(p)&~(OBJECTGRAIN-1))
  76. #define obj_setlf(p, l, f) (obj_geth(p) = (l)|(f))
  77. #define obj_bumplen(p, l) (obj_geth(p) += (l))
  78. #define obj_free(p) (obj_geth(p)&1)
  79. #define obj_setfree(p) (obj_geth(p) |= 1)
  80. #define obj_clearfree(p) (obj_geth(p) &= ~1)
  81. #define obj_pinned(p) (obj_geth(p) & 4)
  82. #define obj_pin(p) (obj_geth(p) |= 4)
  83. #define obj_unpin(p) (obj_geth(p) &= ~4)
  84.  
  85. /*
  86.  * The marking code relies upon the values representing the three mark
  87.  * states to be ordered numerically: NoMark < SoftMark < HardMark.
  88.  */
  89. #define NoMark   0
  90. #define SoftMark 1
  91. #define HardMark 3
  92.  
  93. #define MarkPtr(p, v) _MarkPtr(((unsigned int) (p) & ~(OBJECTGRAIN - 1)), v)
  94. #define ClearMarkPtr(p, v) _ClearMarkPtr(((unsigned int)(p)&~(OBJECTGRAIN-1)),v)
  95. #define IsMarked(p) _IsMarked((unsigned int) (p) & ~(OBJECTGRAIN - 1))
  96.  
  97. #define SOFTREFBAGSIZE 200  /* max number of soft refs to kill in one cycle */
  98.  
  99.  
  100. #ifndef PAGED_HEAPS /************ CONTIGUOUS HEAPS: ********************/
  101.  
  102. #define ValidObject(p)    ((((int)(p)) & (OBJECTGRAIN-1)) == 0 &&            \
  103.              (unsigned char *)(p) >= opmin &&              \
  104.              (unsigned char *)(p) <  opmax)
  105. #define ValidHandle(p)    (((int) (p) & (sizeof(JHandle)-1)) == 0 &&      \
  106.              (unsigned char *)(p) >= hpmin &&            \
  107.              (unsigned char *)(p) <= hpmax)
  108. /* ValidHorO() assumes OBJECTGRAIN=sizeof(JHandle)... */
  109. #define ValidHorO(p)    (((int) (p) & (OBJECTGRAIN-1)) == 0 &&            \
  110.              (unsigned char *)(p) >= hpmin &&        \
  111.              (unsigned char *)(p) <= opmax)
  112. #define SetLimits()                            \
  113.     register unsigned char *const opmin = opool,                \
  114.                            *const opmax = opoollimit,                \
  115.                    *const hpmin = hpool,                      \
  116.                    *const hpmax = hpoollimit-sizeof(JHandle)
  117.  
  118. #define POP_FREE_HANDLE(hp)                         \
  119.     hp = (JHandle *)hpoolfreelist;                     \
  120.     if (hp) {                                \
  121.         hpoolfreelist = (unsigned char *)hp->methods;            \
  122.     }
  123.  
  124. #define PUSH_FREE_HANDLE(hp) \
  125.     hp->methods = (struct methodtable *)hpoolfreelist; \
  126.     hpoolfreelist = (unsigned char *)hp;
  127.  
  128. /* Mark bit access assumes contiguity of handles and objects */
  129. #define MARKINDEX(p)    (((unsigned char *)(p) - hpmin) >> 7)
  130. #define BITOFFSET(p)    ((((unsigned char *)(p) - hpmin) >> 2) & 0x1e)
  131.  
  132. #define _MarkPtr(p, v)    (markbits[MARKINDEX(p)] |= (v) << BITOFFSET(p))
  133. #define _ClearMarkPtr(p, v) (markbits[MARKINDEX(p)] &= ~((v) << BITOFFSET(p)))
  134. #define _IsMarked(p)    ((markbits[MARKINDEX(p)] >> BITOFFSET(p)) &3)
  135.  
  136. /* set the second word in an object (from ptr to header) to 0x55555555 */
  137. #define CHECK_WORD_INDEX 1
  138.  
  139. #define MAP_OVER_HANDLES_FROM_START(MO_hp) {        \
  140.     JHandle *MOH_limit = (JHandle *) hpmax;        \
  141.     for (MO_hp = (JHandle *) hpool; MO_hp <= MOH_limit; MO_hp++) {
  142.  
  143. #define END_MAP_OVER_HANDLES_FROM_START            \
  144.     } /* end for */                    \
  145. } /* end MAP_OVER_HANDLES_FROM_START */
  146.  
  147. #define MAP_OVER_OBJECTS_FROM_START(p) {        \
  148.     unsigned char *MOO_limit = opmax;            \
  149.     unsigned char *MOO_start = opmin;            \
  150.     for (p = opmin;                    \
  151.      p < MOO_limit;                    \
  152.      p += obj_len(p)) {
  153.  
  154. #define END_MAP_OVER_OBJECTS_FROM_START            \
  155.     } /* end for */                    \
  156. } /* end END_MAP_OVER_OBJECTS_FROM_START */
  157.  
  158.  
  159. #else /************ PAGED HEAPS: ********************/
  160.  
  161. /* gc philosophy makes it necessary to detect if an arbitrary int is
  162.  * (possibly) a handle or object ref.
  163.  * A value is (possibly) valid if it is properly aligned, and it 
  164.  * points into a page that has a page map entry of the proper type.
  165.  */
  166. /* assumes ValidHorO already */
  167. #define GetPageMapEntry(p)                          \
  168.          (page_map[((int)(p) - (int)mem_base) >> PTR_2_PAGE_SHIFT])
  169.  
  170. #define ValidObject(p)    ((((int)(p)) & (OBJECTGRAIN-1)) == 0 &&            \
  171.          (void *)(p) >= mem_base &&                        \
  172.          (void *)(p) <  mem_top &&                        \
  173.          (GetPageMapEntry((p)).chunk_size > 0))
  174. #define ValidHandle(p)    (((((int)(p)) & (HANDLEGRAIN-1)) == 0) &&       \
  175.          ((void *)(p) >= mem_base) &&                    \
  176.          ((void *)(p) <  mem_top) &&                    \
  177.          (GetPageMapEntry((p)).chunk_size < 0))
  178. /* ValidHorO() assumes OBJECTGRAIN == HANDLEGRAIN... */
  179. #define ValidHorO(p)    ((((int)(p)) & (HANDLEGRAIN-1)) == 0 &&            \
  180.          (void *)(p) >= mem_base &&                        \
  181.          (void *)(p) <  mem_top &&                        \
  182.          (GetPageMapEntry((p)).chunk_size != 0))
  183.  
  184. #define SetLimits() int SL_dufus = 0
  185.  
  186. /* assumes ValidHorO already */
  187. #define ChunkBase(p)    (void *)                        \
  188.          (((int)(p) & ~(PAGE_ALIGNMENT - 1)) -            \
  189.           (GetPageMapEntry((p)).page_number << PTR_2_PAGE_SHIFT))
  190.          
  191. /* curHanBlkP must be set in advance!!! */
  192. #define POP_FREE_HANDLE(hp)                         \
  193.     hp = (JHandle *)curHanBlkP->freePtr;                     \
  194.     if (hp) {                                    \
  195.         curHanBlkP->freePtr = (unsigned char *)hp->methods;            \
  196.     }
  197.  
  198. /* Can only be called within a MAP_OVER_HANDLES_FROM_START loop 
  199.  * - uses MOH_chunk instead of curHanBlkP for efficiency.
  200.  */
  201. #define PUSH_FREE_HANDLE(hp) \
  202.     hp->methods = (struct methodtable *)MOH_chunk->freePtr; \
  203.     MOH_chunk->freePtr = (unsigned char *)hp;
  204.  
  205. #define MARKINDEX(p)    (((int)(p) & (PAGE_ALIGNMENT - 1)) >> 7)
  206. #define BITOFFSET(p)    ((((int)(p) & (PAGE_ALIGNMENT - 1)) >> 2) & 0x1e)
  207.  
  208. #define _MarkPtr(p, v)    (GetPageMapEntry(p).mark_bits[MARKINDEX(p)] |=       \
  209.                          (v) << BITOFFSET(p))
  210. #define _ClearMarkPtr(p, v) (GetPageMapEntry(p).mark_bits[MARKINDEX(p)] &= \
  211.                              ~((v) << BITOFFSET(p)))
  212. #define _IsMarked(p)    ((GetPageMapEntry(p).mark_bits[MARKINDEX(p)]       \
  213.                           >> BITOFFSET(p)) & 3)
  214.  
  215. /* # of bytes of markbits we need per page: */
  216. #define MARK_BITS_SIZE        ((PAGE_ALIGNMENT / (OBJECTGRAIN * BITSPERCHAR)) * 2)
  217.  
  218. /*
  219.  * Part of Java memory management and garbage collection.
  220.  *
  221.  * This supports a discontiguous gcable heap, which is useful for the
  222.  * Mac OS, or other platforms without good memory mapping support.
  223.  *
  224.  * CHUNKS:
  225.  * Memory is requested from the OS in "Chunks" of n pages, which are
  226.  * PAGE_ALIGNMENT aligned and sized. Handles and objects are allocated out of
  227.  * different chunks.  When more memory is needed, additional chunks can be
  228.  * allocated.  When chunks are free, they may be returned to  the OS.  Chunks
  229.  * don't need to be contiguous.  Handle chunks and object chunks are linked 
  230.  * into seperate, doubly linked lists, which are sorted by chunk address.  On
  231.  * platforms without real "memalign" support, there may be unaligned (wasted)
  232.  * space that precedes the true chunk that we can use for something else 
  233.  * (markbits come to mind).
  234.  */
  235.  
  236. /* fields marked ### MUST BE OBJECT AND/OR HANDLE GRAIN ALIGNED */
  237. typedef struct CHUNK_BLK {    /* a chunk of pages */
  238.     void* chunkHandle;        /* OS handle to this chunk */
  239.     struct CHUNK_BLK *nextPtr;    /* ptr to next chunk header */
  240.     struct CHUNK_BLK *prevPtr;    /* ptr to previous chunk header */
  241.     long chunkFlags;        /* misc flags */
  242.     long allocSize;        /* == (endPtr - startPtr)### */
  243.     long freeCnt;        /* # of free bytes in this chunk */
  244.     unsigned char *startPtr;    /* ptr to starting byte### */
  245.     unsigned char *endPtr;    /* ptr past last byte### */
  246.     unsigned char *freePtr;    /* ptr to first free space CANDIDATE 
  247.     * (may not really be free), or it might be a ptr to a free list
  248.     * of objects, depending on phase of the moon.
  249.     */
  250.     /* users may modify start and end ptrs, but not this one: */
  251.     unsigned char *physEndPtr;                
  252. #ifdef WASTED_SPACE_IN_LEADER
  253.     /* WARNING:  clearLocalMarkBits assumes that only markbits are stored
  254.           * in the waste !!!
  255.           */
  256.     unsigned char *wasteStartPtr; /* ptr to starting wasted byte */
  257.     unsigned char *wasteFreePtr;  /* ptr to first free wasted byte */
  258.                       /* wasteEndPtr == the ChunkBlk pointer */
  259. #endif /* WASTED_SPACE_IN_LEADER*/
  260. } ChunkBlk, *ChunkBlkP;
  261.  
  262. /* CHUNK_BLK->chunkFlags bits: */
  263.      /* set this bit in chunkFlags if any objects in the chunk are pinned */
  264. #define CHUNK_PINNED 1        
  265.  
  266. /* doubly-linked list of handle chunks, in address order: */
  267. extern ChunkBlkP firstHanBlkP;      
  268. extern ChunkBlkP lastHanBlkP;
  269. extern ChunkBlkP curHanBlkP;
  270. /* doubly-linked list of object chunks, in address order: */
  271. extern ChunkBlkP firstObjBlkP;
  272. extern ChunkBlkP lastObjBlkP;
  273. extern ChunkBlkP curObjBlkP;
  274.  
  275. /* store this into the last two words of the chunk to detect overwrites */
  276. /* Odd to make a poor pointer, 111 in the low bits looks like a swapped 
  277.  * free block if a header! */
  278. #define ALMOST_WORD    0x77777777
  279. #define ULTIMATE_WORD  0xBAADDEED  /* Why not. */
  280. /* set the third word in an object (from ptr to header) to 0x55555555 */
  281. #define CHECK_WORD_INDEX 2       
  282.  
  283. /* Macros to abstract out looping over all handles or objects.
  284.  * Note that you can't "break" out of this loop. Use goto or return instead.
  285.  */
  286. #define MAP_OVER_HANDLES_FROM_START(MO_hp) {        \
  287.     ChunkBlkP MOH_chunk = firstHanBlkP;            \
  288.     JHandle *MOH_limit;                    \
  289.     do {                        \
  290.     for (MO_hp = (JHandle *)MOH_chunk->startPtr,    \
  291.          MOH_limit = (JHandle *)MOH_chunk->endPtr;    \
  292.          MO_hp < MOH_limit; MO_hp++) {
  293.  
  294. #define END_MAP_OVER_HANDLES_FROM_START            \
  295.     }  /* end for */                \
  296.     MOH_chunk = MOH_chunk->nextPtr;            \
  297.     } while (MOH_chunk != firstHanBlkP);        \
  298. } /* end MAP_OVER_HANDLES_FROM_START */
  299.  
  300. #define MAP_OVER_OBJECTS_FROM_START(MO_p)   {        \
  301.     ChunkBlkP MOO_chunk = firstObjBlkP;            \
  302.     unsigned char *MOO_limit;                \
  303.     unsigned char *MOO_start;                \
  304.     do {                        \
  305.     for ((MO_p) = MOO_chunk->startPtr,         \
  306.          MOO_start = MOO_chunk->startPtr,        \
  307.          MOO_limit = MOO_chunk->endPtr;        \
  308.          (MO_p) < MOO_limit;            \
  309.          (MO_p) += obj_len(MO_p)) {
  310.  
  311. #define END_MAP_OVER_OBJECTS_FROM_START            \
  312.     }  /* end for */                \
  313.     MOO_chunk = MOO_chunk->nextPtr;            \
  314.     } while (MOO_chunk != firstObjBlkP);        \
  315. } /* end END_MAP_OVER_OBJECTS_FROM_START */
  316.  
  317. #endif /************ END PAGED HEAPS ********************/    
  318.  
  319.  
  320. #ifdef WASTED_SPACE_IN_LEADER
  321. /* following functions defined in gc_md.c: */
  322. void initWastedSpaceInChunk(ChunkBlkP chunk);
  323. void sysCheckWastedSpace(ChunkBlkP chunk);
  324. void clearLocalMarkBits(void);
  325. void* allocMarkBitsLocally(ChunkBlkP blkP);
  326. #else
  327. #define initWastedSpaceInChunk(xxx) 0
  328. #define sysCheckWastedSpace(xxx) 0
  329. #define clearLocalMarkBits() 0
  330. #define allocMarkBitsLocally(xxx) 0
  331. #endif
  332.  
  333. #endif /* !_GC_H_ */
  334.